package org.desktop.web.client.emails.grid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.desktop.web.client.email.grid.property.EmailProperties;
import org.desktop.web.client.emails.proxy.RpcEmailProxy;
import org.desktop.web.client.field.validator.EmailValidator;
import org.desktop.web.client.gui.models.APagingGrid;
import org.desktop.web.client.images.Resources;
import org.desktop.web.client.util.Util;
import org.desktop.web.shared.domain.entities.Email;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.event.StoreAddEvent;
import com.sencha.gxt.data.shared.event.StoreAddEvent.StoreAddHandler;
import com.sencha.gxt.data.shared.event.StoreRecordChangeEvent;
import com.sencha.gxt.data.shared.event.StoreRecordChangeEvent.StoreRecordChangeHandler;
import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
import com.sencha.gxt.widget.core.client.box.MessageBox;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent.CompleteEditHandler;
import com.sencha.gxt.widget.core.client.event.InvalidEvent;
import com.sencha.gxt.widget.core.client.event.InvalidEvent.InvalidHandler;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.Grid.GridCell;
import com.sencha.gxt.widget.core.client.grid.editing.GridEditing;
import com.sencha.gxt.widget.core.client.info.Info;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;

public class EmailsGrid extends
		APagingGrid<Email, PagingLoadConfig, EmailProperties> {

	private ColumnConfig<Email, String> ccEmail;
	EmailProperties props = null;
	private GridEditing<Email> editing;

	private Map<Integer, Email> addedMap = new HashMap<Integer, Email>();

	private Map<Integer, Email> updatedMap = new HashMap<Integer, Email>();

	private Map<Integer, Email> deletedMap = new HashMap<Integer, Email>();

	public EmailsGrid(int pageSize, APagingGrid<?, ?, ?> childGrid,
			boolean remoteSort, APagingGrid<?, ?, ?> parent) {
		super(pageSize, childGrid, remoteSort, parent);
		this.props = getPropertyAccess();
	}

	public EmailsGrid(int pageSize, APagingGrid<?, ?, ?> childGrid,
			boolean remoteSort) {
		super(pageSize, childGrid, remoteSort);
		this.props = getPropertyAccess();
	}

	public EmailsGrid(int pageSize, APagingGrid<?, ?, ?> parent) {
		super(pageSize, parent);
		this.props = getPropertyAccess();
	}

	public EmailsGrid(int pageSize, boolean remoteSort,
			APagingGrid<?, ?, ?> parent) {
		super(pageSize, remoteSort, parent);
		this.props = getPropertyAccess();
	}

	public EmailsGrid(int pageSize) {
		super(pageSize);
		this.props = getPropertyAccess();
	}

	@Override
	public EmailProperties getPropertyAccess() {
		return GWT.create(EmailProperties.class);
	}

	@Override
	public void initProxy() {
		setRpcProxy(new RpcEmailProxy());

	}

	public enum Name {
		EMAIL
	}

	private ColumnConfig<Email, String> getEmailColumn() {
		if (ccEmail == null) {
			ccEmail = new ColumnConfig<Email, String>(props.email(), 300,
					"Email");
		}
		return this.ccEmail;
	}

	@Override
	public List<ColumnConfig<Email, ?>> getColumnsConfig() {
		List<ColumnConfig<Email, ?>> ll = new ArrayList<ColumnConfig<Email, ?>>();
		ll.add((this.ccEmail = getEmailColumn()));
		return ll;
	}

	@Override
	public ModelKeyProvider<? super Email> key() {
		// TODO Auto-generated method stub
		return getPropertyAccess().idEmail();
	}

	@Override
	public Widget asWidget() {
		setEditable(true);
		return super.asWidget();

	}

	@Override
	public ToolBar createTopToolBar() {
		ToolBar toolbar = new ToolBar();
		TextButton addEmail = new TextButton();
		addEmail.setText("Add Email");
		addEmail.setIcon(Resources.IMAGES.add());
		addEmail.addSelectHandler(new SelectHandler() {

			@Override
			public void onSelect(SelectEvent event) {
				final Email email = new Email();
				email.setEmail("anEmail");
				email.setIdEmail(Random.nextInt(Integer.MAX_VALUE));
				getGridEditing().cancelEditing();
				getStore().add(0, email);
				int row = getStore().indexOf(email);
				GridCell cell = new GridCell(row, 0);
				getGridEditing().startEditing(cell);

			}
		});TextButton removeEmail = new TextButton();
		removeEmail.setText("Remove Email");
		removeEmail.setIcon(Resources.IMAGES.delete());
		removeEmail.addSelectHandler(new SelectHandler() {

			@Override
			public void onSelect(SelectEvent event) {
				if(getGrid().getSelectionModel().getSelectedItem()==null){
					Util.showAlert("Attenzione", "Selezionare la riga da aliminare", MessageBox.ICONS.error());
					return;
				}
				
				final Email email = getGrid().getSelectionModel().getSelectedItem();
				deletedMap.put(email.getIdEmail(), email);
				updatedMap.remove(email.getIdEmail());
				addedMap.remove(email.getIdEmail());
				getStore().remove(email);
			}
		});
		
		toolbar.add(addEmail);
		toolbar.add(removeEmail);
		return toolbar;
	}

	@Override
	protected void defineColumnsEditing() {
		TextField email = new TextField();
		email.setAllowBlank(false);
		email.addValidator(new EmailValidator());
		getGridEditing().addEditor(this.ccEmail, email);
	}

	@Override
	protected void addStoreHandlers() {
		getStore().addStoreAddHandler(new StoreAddHandler<Email>() {

			@Override
			public void onAdd(StoreAddEvent<Email> event) {
				Email e = event.getItems().get(event.getIndex());
				addedMap.put(e.getIdEmail(), e);
//				getStore().commitChanges();

			}
		});
		getStore().addStoreRecordChangeHandler(
				new StoreRecordChangeHandler<Email>() {

					@Override
					public void onRecordChange(
							StoreRecordChangeEvent<Email> event) {
						Email e = event.getRecord().getModel();
						if(!addedMap.containsKey(e.getIdEmail())){
							updatedMap.put(e.getIdEmail(), e);
							return;
						}
//						getStore().commitChanges();
						//la riga è stata aggiunta ex-novo, quindi va inserita nell'elenco delle email da aggiungere.
						addedMap.put(e.getIdEmail(), e);

					}
				});
	}

	public Map<Integer, Email> getAddedMap() {
		return addedMap;
	}

	public Map<Integer, Email> getUpdatedMap() {
		return updatedMap;
	}

	public Map<Integer, Email> getDeletedMap() {
		return deletedMap;
	}

	@Override
	protected void onCompleteEditing(GridEditing<Email> gridEditing) {
		
		gridEditing.addCompleteEditHandler(new CompleteEditHandler<Email>() {

			@Override
			public void onCompleteEdit(CompleteEditEvent<Email> event) {
				Email item = event.getSource().getEditableGrid().getSelectionModel().getSelectedItem();
				int row = getStore().indexOf(item);
				
			}
		});
	}

}
